package org.shj.netty.chartper2.aio;

import java.io.IOException;
import java.nio.ByteBuffer;
import java.nio.channels.AsynchronousSocketChannel;
import java.nio.channels.CompletionHandler;
import java.util.Date;

public class ReadCompletionHandler implements CompletionHandler<Integer, ByteBuffer>{
	
	private AsynchronousSocketChannel channel;
	
	public ReadCompletionHandler(AsynchronousSocketChannel channel){
		if (channel != null)
			this.channel = channel;
	}

	@Override
	public void completed(Integer result, ByteBuffer attachment) {
		System.out.println("ReadCompletionHandler.completed()");
		attachment.flip();
		byte[] body = new byte[attachment.remaining()];
		attachment.get(body);
		
		try{
			String req = new String(body, "UTF-8");
			System.out.println("The time server receive order: " + body);
			
			String currentTime = "QUERY TIME ORDER".equalsIgnoreCase(req) ? new Date(System.currentTimeMillis()).toString() : "Bad Order";
			doWrite(currentTime);
		}catch(Exception e){
			e.printStackTrace();
		}
		
	}
	
	private void doWrite(String currentTime){
		System.out.println("ReadCompletionHandler.doWrite()");
		if(currentTime != null && currentTime.trim().length() > 0){
			byte[] bytes = (currentTime).getBytes();
			ByteBuffer writeBuffer = ByteBuffer.allocate(bytes.length);
			writeBuffer.put(bytes);
			writeBuffer.flip();
			
			channel.write(writeBuffer, writeBuffer, new CompletionHandler<Integer, ByteBuffer>(){
				public void completed(Integer result, ByteBuffer buffer){
					System.out.println("inner.completed()");
					if(buffer.hasRemaining()){
						channel.write(buffer, buffer, this);
					}
				}
				
				public void failed(Throwable exc, ByteBuffer attachment){
					System.out.println("inner.failed()");
					try{
						channel.close();
					}catch(IOException e){
						//ignore on close
					}
				}
			});
		}
	}

	@Override
	public void failed(Throwable exc, ByteBuffer attachment) {
		System.out.println("ReadCompletionHandler.failed()");
		try{
			channel.close();
		}catch(IOException e){
			e.printStackTrace();
		}
	}
	

}
